package com.biz.primus.ms.oms.service.core;


import com.biz.primus.base.exception.BizSilentException;
import com.biz.primus.base.vo.PageResult;
import com.biz.primus.common.utils.Copier;
import com.biz.primus.common.utils.CopyUtils;
import com.biz.primus.model.oms.enums.CancelType;
import com.biz.primus.model.oms.enums.OrderDeliveryState;
import com.biz.primus.model.oms.enums.OrderState;
import com.biz.primus.model.oms.exception.OmsExceptions;
import com.biz.primus.model.oms.vo.*;
import com.biz.primus.ms.base.service.AbstractBaseService;
import com.biz.primus.ms.oms.dao.po.OmsOrder;
import com.biz.primus.ms.oms.dao.po.OmsOrderItem;
import com.biz.primus.ms.oms.dao.po.OrderPaymentInfo;
import com.biz.primus.ms.oms.dao.po.returns.OmsRefund;
import com.biz.primus.ms.oms.dao.po.returns.OmsReturn;
import com.biz.primus.ms.oms.dao.repository.*;
import com.biz.primus.ms.oms.dao.specification.OmsOrderItemSpecification;
import com.biz.primus.ms.oms.dao.specification.OmsOrderSpecification;
import com.biz.primus.ms.oms.service.collection.OrderDataConverter;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author  LGJ
 * @date 2017/11/10
 */

@Service
@Slf4j
public class OrderQueryServiceImpl extends AbstractBaseService implements OrderQueryService {

    @Autowired
    private OmsOrderRepository omsOrderRepository;

    @Autowired
    private OrderDataConverter orderDataConverter;

    @Autowired
    private OmsPaymentRepository omsPaymentRepository;

    @Autowired
    private OmsOrderReturnRepository omsOrderReturnRepository;

    @Autowired
    private OmsRefundRepository omsRefundRepository;

    @Autowired
    private OmsOrderItemRepository omsOrderItemRepository;
    @Override
    public PageResult<OmsOrderVo> findOrders(OrderQueryVo orderQueryVo) {
        Page<OmsOrder> page = omsOrderRepository.findAll(new OmsOrderSpecification(orderQueryVo), orderQueryVo.toPageRequest());
        List<OmsOrderVo> result = page.getContent().stream().map(orderDataConverter::orderPo2Vo).collect(Collectors.toList());
        return PageResult.of(page.getNumber(),page.getTotalPages(),result);
    }

    @Override
    public OmsOrderVo orderQueryDetail(String depotCode, String orderCode) {
        OmsOrder omsOrder = omsOrderRepository.findByOrderCode(orderCode);
        if(omsOrder.getCancelType() == CancelType.closed ||omsOrder.getCancelType() == CancelType.canceled){
            throw new BizSilentException(OmsExceptions.ORDER_CANCEL);
        }

        if(!Objects.equals(depotCode,omsOrder.getDepotCode())){
            throw  new BizSilentException(OmsExceptions.DEPOT_ERROR);
        }

        OmsOrderVo order = orderDataConverter.orderPo2Vo(omsOrder);
        //todo items,payments


        return order;
    }

    @Override
    public PageResult<OmsOrderVo> managementOrderQuery(OrderQueryVo orderQueryVo) {
        Page<OmsOrder> omsOrders = omsOrderRepository.findAll(new OmsOrderSpecification(orderQueryVo),orderQueryVo.toPageRequest());
        List<OmsOrderVo> result = omsOrders.getContent().stream()
                .map(po -> Copier.from(po).to(new OmsOrderVo())).collect(Collectors.toList());
        return   PageResult.of(omsOrders.getNumber(),omsOrders.getTotalPages(),result);
    }

    @Override
    public OmsOrderRespVo getOrderDetail(String orderCode) {
        //订单基础信息
        OmsOrder omsOrder = omsOrderRepository.findByOrderCode(orderCode);
        if(omsOrder==null){
            throw new BizSilentException(OmsExceptions.ORDER_NOT_FOUNT);
        }
        OmsOrderRespVo omsOrderRespVo = orderDataConverter.orderPo2RespVo(omsOrder);
        //用户信息

        //操作记录

        //出库信息

        //订单转支付

        //商品拆分信息

        //配送信息
        //支付信息
        List<OrderPaymentInfo> orderPaymentInfos = omsPaymentRepository.findByOrderId(omsOrder.getId());
        if(!CollectionUtils.isEmpty(orderPaymentInfos)){
            List<OmsPaymentVo>  omsPaymentVos =orderPaymentInfos.stream().map(req->{
                OmsPaymentVo omsPaymentVo=new OmsPaymentVo();
                CopyUtils.copyProperties(req,omsPaymentVo);
                return omsPaymentVo;
            }).collect(Collectors.toList());
            omsOrderRespVo.setPayments(omsPaymentVos);
        }
        //退货信息
        OmsReturn omsReturn = omsOrderReturnRepository.findByOrderId(omsOrder.getId());
        omsOrderRespVo = orderDataConverter.omsreturn2RespVo(omsReturn,omsOrderRespVo);

        //退款信息
        OmsRefund omsRefund = omsRefundRepository.findByReturnId(omsOrder.getId());
        if(!Objects.isNull(omsRefund)){
            omsOrderRespVo = orderDataConverter.omsrefund2RespVo(omsRefund,omsOrderRespVo);
        }
        return omsOrderRespVo;
    }

    @Override
    public OmsOrderHistoryVo getOrderHistoryInfoByUserId(OrderQueryVo orderQueryVo) {
        //最后一条订单
        OmsOrder lasetOmsOrder = omsOrderRepository.findTop1ByUserIdOrderByCreateTimestampDesc(orderQueryVo.getUserId());
        //订单总金额
        Integer orderAmount = omsOrderRepository.findAmountByUserId(orderQueryVo.getUserId());
        Integer orderCount = omsOrderRepository.findOrderCountByUserId(orderQueryVo.getUserId());
        OmsOrderHistoryVo omsOrderHistoryVo = new OmsOrderHistoryVo();
        omsOrderHistoryVo.setOrderCount(orderCount);
        omsOrderHistoryVo.setOrderAmount(orderAmount);
        omsOrderHistoryVo.setLastOrderTime(lasetOmsOrder.getCreateTimestamp());
        omsOrderHistoryVo.setLastOrderCode(lasetOmsOrder.getOrderCode());
        return omsOrderHistoryVo;
    }


    @Override
    public PageResult<OmsHistoryOrderProductVo> getOrderProductByUserId(OrderQueryVo orderQueryVo) {
        Page<OmsOrderItem>  omsOrderItemPage = omsOrderItemRepository.findAll(new OmsOrderItemSpecification(orderQueryVo),orderQueryVo.toPageRequest());
        List<OmsHistoryOrderProductVo> omsHistoryOrderProductVos = omsOrderItemPage.getContent().stream().map(po -> orderItem2HistoryOrder(po)).collect(Collectors.toList());
        return PageResult.of(omsOrderItemPage.getNumber(),omsOrderItemPage.getTotalPages(),omsHistoryOrderProductVos);
    }


    public OmsHistoryOrderProductVo orderItem2HistoryOrder(OmsOrderItem omsOrderItem){
        OmsHistoryOrderProductVo omsHistoryOrderProductVo =new OmsHistoryOrderProductVo();
        omsHistoryOrderProductVo.setDepotName(omsOrderItem.getOrder().getDepotName());
        omsHistoryOrderProductVo.setName(omsOrderItem.getProductName());
        omsHistoryOrderProductVo.setOrderTime(omsOrderItem.getOrder().getCreateTimestamp().toLocalDateTime());
        omsHistoryOrderProductVo.setPrice(omsOrderItem.getFinalPrice());
        omsHistoryOrderProductVo.setQuantity(omsOrderItem.getQuantity());
        return omsHistoryOrderProductVo;
    }


    @Override
    public OmsOrderRespVo getApplyforReturn(String orderCode) {
        OmsOrder omsOrder = omsOrderRepository.findByOrderCode(orderCode);

        //只有已发货的订单才能申请退货
        if(omsOrder.getDeliveryState() == OrderDeliveryState.for_outbound ||
                omsOrder.getDeliveryState() == OrderDeliveryState.for_take_their ){
            throw  new BizSilentException(OmsExceptions.STATE_ERROR);
        }

        return getOrderDetail(orderCode);
    }
}
